package com.itlong.cloud.controller.pad;

import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.app.AppFaceRecognitionPaymentDTO;
import com.itlong.cloud.POJO.DTO.app.AppUploadPassRecordDTO;
import com.itlong.cloud.POJO.PO.ProjectPO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.app.*;
import com.itlong.cloud.POJO.VO.operate.OperateFaceApplyInfoVO;
import com.itlong.cloud.POJO.VO.operate.OperateProjectDetailVO;
import com.itlong.cloud.POJO.VO.property.CloudElevatorVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.*;
import com.itlong.cloud.enumerate.ecode.AppErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.ErrorCode;
import com.itlong.cloud.enumerate.ecode_en.AppErrorCodeEnumEN;
import com.itlong.cloud.enumerate.ecode_en.BaseErrorCodeEnumEN;
import com.itlong.cloud.equip.app.IAppDeviceServiceClient;
import com.itlong.cloud.equip.commons.ICloudEntranceServiceClient;
import com.itlong.cloud.equip.property.ICloudIntercomServiceClient;
import com.itlong.cloud.equip.property.IPadFaceSyncDataServiceClient;
import com.itlong.cloud.iottp.IIotServerServiceClient;
import com.itlong.cloud.project.operate.IOperateFaceApplyServiceClient;
import com.itlong.cloud.project.operate.IOperateProjectServiceClient;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.app.IAppHomeServiceClient;
import com.itlong.cloud.user.app.IAppPadFaceServiceClient;
import com.itlong.cloud.user.app.IAppRegisterServiceClient;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import sun.misc.BASE64Decoder;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <desc>
 * 平板人脸识别控制器。
 * </desc>
 *
 * @createDate 2018-05-15.
 */
@RestController
@RequestMapping("/padFace")
public class AppPadFaceController {


    private static final Logger LOG = LoggerFactory.getLogger(AppPadFaceController.class);

    @Value("${" + PlatformConstants.APP_REQUEST_PARAMS_ENCRYPT_KEY + "}")
    public String APP_REQUEST_PARAMS_ENCRYPT_KEY;
    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;
    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;
    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;
    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;
    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;
    @Value("${" + PlatformConstants.H5_PAYMENT_HTML + "}")
    public String H5_PAYMENT_HTML;



    @Autowired
    IAppPadFaceServiceClient iAppPadFaceServiceClient;

    @Autowired
    IAppHomeServiceClient iAppHomeServiceClient;

    @Autowired
    ICloudIntercomServiceClient iCloudIntercomServiceClient;

    @Autowired
    IOperateFaceApplyServiceClient iOperateFaceApplyServiceClient;

    @Autowired
    IOperateProjectServiceClient iOperateProjectServiceClient;

    @Autowired
    IAppRegisterServiceClient iAppRegisterServiceClient;

    @Autowired
    IPadFaceSyncDataServiceClient iPadFaceSyncDataServiceClient;

    @Autowired
    RedisService redisService;

    @Autowired
    IAppDeviceServiceClient iAppDeviceServiceClient;

    @Autowired
    ICloudEntranceServiceClient iCloudEntranceServiceClient;

    @Autowired
    IIotServerServiceClient iIotServerServiceClient;

    /**
     * <desc>
     * 人脸识别扣费。
     * </desc>
     *
     * @param paymentDTO
     * @param sign       签名
     * @return
     * @author shengen.T
     * @createDate 2018-05-14
     */
    @RequestMapping(value = "/payment", method = RequestMethod.POST)
    @ResponseBody
    public MessageVO faceRecognitionPayment(AppFaceRecognitionPaymentDTO paymentDTO, String sign) {
        MessageVO messageVO;
        try {
//            //验证签名
            if (!Md5EncryptUtil.checkAppSign(paymentDTO, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            //判断项目编号
            if (StringUtils.isBlank(paymentDTO.getProjectId()) || !paymentDTO.getProjectId().matches("[0-9]{8}")) {
                return new MessageVO(AppErrorCodeEnum.PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            //判断人脸ID
            if (StringUtils.isBlank(paymentDTO.getUId())) {
                return new MessageVO(AppErrorCodeEnum.FACE_ID_EMPTY_ERROR.getErrorCode());
            }
            //判断设备唯一编号
            if (StringUtils.isBlank(paymentDTO.getDeviceUnique())) {
                return new MessageVO(AppErrorCodeEnum.DEVICE_UNIQUE_EMPTY_ERR.getErrorCode());
            }
            //判断该项目设备云服务费时间是否过期
//            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
//            String endTime = iAppPadFaceServiceClient.getDeviceCloudServiceCostEndTime(paymentDTO.getProjectId());
//            Date endDate = dateFormat.parse(endTime);
//            Date nowDate = dateFormat.parse(dateFormat.format(new Date()));
//            if(StringUtils.isNotEmpty(endTime) && nowDate.compareTo(endDate)>0){
//                return new MessageVO(AppErrorCodeEnum.PAD_IS_NOT_NORMAL.getErrorCode());
//            }
            if(paymentDTO.getType().equals("3")){
                paymentDTO.setType("2");
            }
            CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
            JSONObject js = new JSONObject();//返回数据对象
            if(paymentDTO.getType().equals("3")){
                paymentDTO.setType("2");
            }
            //门禁或者电梯
            if ("1".equals(paymentDTO.getType()) || "2".equals(paymentDTO.getType())) {
                // 检查用户信息
                Map<String, Object> res = iAppHomeServiceClient.checkUserInProject(paymentDTO.getUId(), paymentDTO.getProjectId());
                //人脸识别用户姓名
                js.put("userName", (null == res.get("userName")) ? "" : res.get("userName").toString());
                if (res != null) {
                    if ("0".equals(res.get("userProjectStatus")==null?"":res.get("userProjectStatus").toString())) {
                        js.put("type", 4);//冻结
                        return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), js);
                    }
                    if ("2".equals(res.get("userStatus").toString())) {
                        js.put("type", 5);//禁用
                        return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), js);
                    }
                    //项目被禁用
                    if ("1".equals(res.get("projectStatus").toString())) {
                        return new MessageVO(AppErrorCodeEnum.PAD_PROJECT_FORBIDDEN.getErrorCode());
                    }

                } else {
                    return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode());
                }

                Map<String,Object> arrearageMap = iAppRegisterServiceClient.getPadUserStatus(paymentDTO);
                Integer arearageStatus = (Integer)arrearageMap.get("arearageStatus");

                //电梯
                if ("1".equals(paymentDTO.getType()) && arearageStatus!=7) {
                    //电梯设备信息
                    List<AppFloorDevicesVO> floors = iAppDeviceServiceClient.getFloorDevicesForPad(paymentDTO.getUId(), paymentDTO.getProjectId(), 0, arearageStatus);
                    String deviceUniqueTmp = String.format("%s%s%s", paymentDTO.getProjectId(), paymentDTO.getType(), paymentDTO.getDeviceUnique());

                    //检测用户是否有当前设备使用权限
                    boolean isOne = floors.stream().filter(floorOne -> (floorOne != null) && (deviceUniqueTmp.equals(floorOne.getDeviceUnique()))).findFirst().isPresent();
                    if (isOne) {  //当前用户有该设备权限
                        for (AppFloorDevicesVO floorInfo : floors) {
                            //是否有该电梯权限并做相应业务逻辑处理
                            if (floorInfo.getDeviceUnique().equals(deviceUniqueTmp)) {
                                // BigDecimal accountMoney = iAppPadFaceServiceClient.getUserAccountMoney(paymentDTO.getUId());
                                if(StringUtils.isNotBlank(floorInfo.getLiveFloor())) {
                                    //取真实楼层
                                    String realFloor = iAppHomeServiceClient.batchGetRealFloorList(deviceUniqueTmp, floorInfo.getLiveFloor());
                                    if (StringUtils.isBlank(realFloor)) {
                                        LOG.info(String.format("【平板_预约呼梯】楼层号信息有误，设备号：%s 楼层：s% ", deviceUniqueTmp, floorInfo.getLiveFloor()));
                                        return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode());
                                    }
                                    //调取IOT预约呼梯
                                    iAppDeviceServiceClient.cloudElevatorCall(deviceUniqueTmp, CloudElevatorSourceEnum.ITLONG_CLOUD_ELEVATOR.getDescription(), "", "",
                                            realFloor, CloudElevatorCallTypeEnum.IN.getType(), null, CallElevatorSourceTypeEnum.APP.getType(),null,null, null,null, null, paymentDTO.getUId(), "");
                                }
//                        if(null==accountMoney){
//                            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),2);
//                        }
//                        Integer isNormal = (standard.compareTo(accountMoney)==1)?1:2;//1正常 2欠费
                                if(arearageStatus == 8){
                                    js.put("type",arearageStatus);
                                }else{
                                    js.put("type", 1);
                                }
                                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), js);
                            }
                        }
                    }
                } else if ("2".equals(paymentDTO.getType()) && arearageStatus!=7) {  //门禁

                    //获取有权限的门禁设备信息
                    List<AppDoorDevicesVO> doors = iAppDeviceServiceClient.getDoorDevices(paymentDTO.getUId(), paymentDTO.getProjectId(), 0);
                    String deviceUniqueTmp = String.format("%s%s%s", paymentDTO.getProjectId(), paymentDTO.getType(), paymentDTO.getDeviceUnique());

                    //检测用户是否有当前设备使用权限
                    boolean isOne = doors.stream().filter(door -> (door != null) && (deviceUniqueTmp.equals(door.getDeviceUnique()))).findFirst().isPresent();
                    if (isOne) {  //当前用户无该设备权限
                        for (AppDoorDevicesVO doorInfo : doors) {
                            //是否有该门禁权限并做相应业务逻辑处理
                            if (doorInfo.getDeviceUnique().equals(deviceUniqueTmp)) {
                                Integer entranceType = iAppDeviceServiceClient.getEntranceTypeInfo(deviceUniqueTmp);
//                                if(entranceType==PropertyEquipTypeEnum.CLOUD_WIPPEN_DEVICE.getType()) {//
                                    //如果设备为云联动器则进行IOT呼梯
                                    Map<String,Object> entrance = iCloudEntranceServiceClient.getMainDeviceUniqueAndProductKey(deviceUniqueTmp);
                                    iCloudEntranceServiceClient.wippenOpenOrCloseCtrl("itlong", entrance.get("deviceUnique").toString(),
                                            Integer.valueOf(deviceUniqueTmp.substring(deviceUniqueTmp.length() - 4, deviceUniqueTmp.length())).toString(),
                                            CloudEntranceOpenTypeEnum.OPEN.getType().toString(), "1", entrance.get("productKey").toString(), paymentDTO.getUId(),
                                            IotOpenDoorSourceEnum.ITLONG_PAD.getType().toString(),null,null, correlationId.getId(),"0",null);
//                                }
//                        BigDecimal accountMoney = iAppPadFaceServiceClient.getUserAccountMoney(paymentDTO.getUId());
//                        if(null==accountMoney){
//                            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),2);
//                        }
//                        Integer isNormal = (standard.compareTo(accountMoney)==1)?1:2;//1正常 2欠费
                                if(arearageStatus == 8){
                                    js.put("type",arearageStatus);
                                }else{
                                    js.put("type", 1);
                                }
                                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), js);
                            }
                        }
                    }
                }
                // 业主相关鉴权未通过,现进行访客鉴权
                //电梯
                if ("1".equals(paymentDTO.getType())) {
                    //获取当前访客当前时间下的所有有权电梯
                    //电梯设备信息
                    List<AppPadVisitorElevatorInfoVO> floors = iAppPadFaceServiceClient.getElevatorInfoByFaceId(paymentDTO.getUId());
                    String deviceUniqueTmp = String.format("%s%s%s", paymentDTO.getProjectId(), paymentDTO.getType(), paymentDTO.getDeviceUnique());
                    boolean isOne = floors.stream().filter(floorOne -> (floorOne != null) && (deviceUniqueTmp.equals(floorOne.getDeviceUnique()))).findFirst().isPresent();
                    if (isOne) {  //当前用户无该设备权限
                        List<String> floors2 = new ArrayList<>();
                        floors2.add(deviceUniqueTmp);
                        List<AppPadVisitorElevatorInfoVO> result = floors.stream().filter((AppPadVisitorElevatorInfoVO vo) -> floors2.contains(vo.getDeviceUnique())).collect(Collectors.toList());
                        if (result.size() > 0) {
                            iAppDeviceServiceClient.cloudElevatorCall(deviceUniqueTmp, CloudElevatorSourceEnum.ITLONG_CLOUD_ELEVATOR.getDescription(), "", "",
                                    result.get(0).getFloorNum(), CloudElevatorCallTypeEnum.IN.getType(), null, CallElevatorSourceTypeEnum.APP.getType(),null,null,null, null, null, paymentDTO.getUId(), "");
                            //进行访客验证 type类型为6
                            //获取访客姓名
                            String visitorName = iAppHomeServiceClient.getVisitorName(paymentDTO.getUId(), paymentDTO.getProjectId());
                            js.put("userName", (null == visitorName ? "" : visitorName));
                            js.put("type", 6);
                            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), js);
                        }
                    }
                } else {//门禁
                    //获取当前访客当前时间下的所有有权门禁
                    List<AppDoorDevicesVO> doors = iAppPadFaceServiceClient.getDoorInfoByFaceId(paymentDTO.getUId());
                    String deviceUniqueTmp = String.format("%s%s%s", paymentDTO.getProjectId(), paymentDTO.getType(), paymentDTO.getDeviceUnique());
                    boolean isOne = doors.stream().filter(door -> (door != null) && (deviceUniqueTmp.equals(door.getDeviceUnique()))).findFirst().isPresent();
                    if (isOne) {  //当前用户无该设备权限
                        Map<String,Object> entrance = iCloudEntranceServiceClient.getMainDeviceUniqueAndProductKey(deviceUniqueTmp);
                        Integer entranceType = iAppDeviceServiceClient.getEntranceTypeInfo(deviceUniqueTmp);
//                        if(entranceType==PropertyEquipTypeEnum.CLOUD_WIPPEN_DEVICE.getType()){//
                            iCloudEntranceServiceClient.wippenOpenOrCloseCtrl("itlong", entrance.get("deviceUnique").toString(),
                                    Integer.valueOf(deviceUniqueTmp.substring(deviceUniqueTmp.length() - 4, deviceUniqueTmp.length())).toString(),
                                    CloudEntranceOpenTypeEnum.OPEN.getType().toString(), "1", entrance.get("productKey").toString(), paymentDTO.getUId(),
                                    IotOpenDoorSourceEnum.ITLONG_PAD.getType().toString(),null,null, correlationId.getId(),"0",null);
//                        }
                        //获取访客姓名
                        String visitorName = iAppHomeServiceClient.getVisitorName(paymentDTO.getUId(), paymentDTO.getProjectId());
                        js.put("userName", (null == visitorName ? "" : visitorName));
                        //进行访客验证 type类型为6
                        js.put("type", 6);
                        return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), js);
                    }
                }
                //根据userId和projectId查询该用户是否欠费
                if (arearageStatus > 0 && arearageStatus == 7) {
                    js.put("type", arearageStatus);//欠费
                    return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), js);
                }
                js.put("type", 3);//陌生用户
                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), js);
            } else {
                return new MessageVO(AppErrorCodeEnum.DEVICE_TYPE_INVALID_ERR.getErrorCode());
            }
        } catch (Exception e) {
            throw new DataAccessException("【APP_首页版块】人脸认证扣费失败", e);
        }
    }


    /**
     * <desc>
     *      平板设备验证(在线离线相结合)。
     * </desc>
     *
     * @param type      设备类型；1为梯控，2门禁 3云联动器
     * @param projectId 项目ID
     * @param deviceId 设备唯一码deviceUnquie
     * @return
     * @author Qiang.S
     * @createDate 2018/05/14
     */
    @RequestMapping(path ="/deviceVerifyOffLine",method = RequestMethod.POST)
    @ResponseBody
    public MessageVO deviceVerifyOffLine(String type, String projectId,String deviceId, String createTime,String sign,String language,String padDeviceUnique,String emId,String baiduId) {
        MessageVO messageVO;
        try {
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("type",type);
            params.put("projectId",projectId);
            params.put("deviceId",deviceId);
            params.put("padDeviceUnique",padDeviceUnique);
            params.put("emId",emId);
            params.put("baiduId",baiduId);
            //验证签名
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            //判断必要信息是否为空
            else if (StringUtils.isBlank(type)||StringUtils.isBlank(createTime)|| StringUtils.isEmpty(projectId) || StringUtils.isEmpty(language) || StringUtils.isEmpty(deviceId) || StringUtils.isEmpty(padDeviceUnique) || StringUtils.isEmpty(emId) || StringUtils.isEmpty(baiduId)){
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode(): BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                return new MessageVO(errorCode);
            }
            deviceId = deviceId.substring(9,13);
            //判断项目是否存在
            if (iOperateProjectServiceClient.checkProjectExist(projectId) <= 0) {
                return new MessageVO(AppErrorCodeEnum.PAD_PROJECT_NOT_EXISTS.getErrorCode());
            }
            //判断当前项目是否被禁用
            if (iAppPadFaceServiceClient.checkProjectForbidden(projectId) > 0) {
                return new MessageVO(AppErrorCodeEnum.PAD_PROJECT_FORBIDDEN.getErrorCode());
            }
            //判断当前平板设备唯一码的设备是否存在或是否被禁用
            String padStatus = iAppPadFaceServiceClient.getPadDeviceExist(padDeviceUnique);
            if(padStatus == null || "".equals(padStatus)){
                return new MessageVO(AppErrorCodeEnum.PAD_DEVICE_NOT_EXISTS_STATUS.getErrorCode());
            }
            //设备禁用
            if ("2".equals(padStatus)) {
                return new MessageVO(AppErrorCodeEnum.PAD_DEVICE_FORBIDDEN.getErrorCode());
            }
            String status = null;//设备状态
            //判断项目下是否有此设备,是否被禁用
            // 梯控
            if ("1".equals(type)) {
                status = iAppPadFaceServiceClient.elevatorAuthorityCheck(projectId, deviceId, "", "");
            }
            //门禁
            else if ("2".equals(type) || "3".equals(type)) {
                status = iAppPadFaceServiceClient.entranceAuthorityCheck(projectId, deviceId, "");
            }
            //返回空则无此设备
            if (status == null || "".equals(status)) {
                return new MessageVO(AppErrorCodeEnum.PAD_DEVICE_NOT_EXISTS.getErrorCode());
            }
            //设备禁用
            if ("2".equals(status)) {
                return new MessageVO(AppErrorCodeEnum.PAD_DEVICE_FORBIDDEN.getErrorCode());
            }
            //校验该平板机号有没被其它设备占用
            if(iAppPadFaceServiceClient.isDeviceIdUserd(baiduId,padDeviceUnique)>0){
                return new MessageVO(AppErrorCodeEnum.PAD_DEVICEID_IS_USERD.getErrorCode());
            }
            //根据baiduId来更新绑定百度识别授权码的设备信息
            iAppPadFaceServiceClient.bingBaiDuAuthCode(projectId,emId,baiduId,padDeviceUnique,"1");
            //验证iot相关
            iAppPadFaceServiceClient.registerPadIot(padDeviceUnique);
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【App_deviceVerify】设备验证失败", e);
        }
        return messageVO;
    }

    /**
     * <desc>
     * 平板登陆验证(工程人员)。
     * </desc>
     *
     * @param projectId 项目编号
     * @param userName  帐号
     * @param password  登陆密码
     * @return
     * @author Qiang.S
     * @createDate 2018/05/14
     */
    @RequestMapping(path = "/engineerLoginVerify", method = RequestMethod.POST)
    @ResponseBody
    public MessageVO engineerLoginVerify(String projectId, String userName, String password, String createTime, String sign, String language) {
        MessageVO messageVO;
        try {
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("createTime", createTime);
            params.put("language", language);
            params.put("projectId", projectId);
            params.put("userName", userName);
            params.put("password", password);
            //验证签名
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            //判断必要信息是否为空
            else if (StringUtils.isBlank(projectId) || StringUtils.isBlank(userName) || StringUtils.isBlank(createTime) || StringUtils.isEmpty(password) || StringUtils.isEmpty(language)) {
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? BaseErrorCodeEnum.NOT_PARAM.getErrorCode() : BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                return new MessageVO(errorCode);
            }
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), true);
            //判断帐号是否存在
            int x = iAppPadFaceServiceClient.engineerLoginExistsVerify(userName);
            if (x == 0) {
                messageVO = new MessageVO(AppErrorCodeEnum.PAD_ENGINEER_NOT_EXISTS.getErrorCode());
                return messageVO;
            }

            //判断帐号是否管辖该项目
            int y = iAppPadFaceServiceClient.engineerLoginProjectVerify(projectId, userName);
            if (y == 0) {
                messageVO = new MessageVO(AppErrorCodeEnum.PAD_ENGINEER_VERIFY_PROJECT_FAIL.getErrorCode());
                return messageVO;
            }

            //判断帐号密码是否正确
            int i = iAppPadFaceServiceClient.engineerLoginVerify(projectId, userName, Md5EncryptUtil.md5(password));
            if (i == 0) {
                messageVO = new MessageVO(AppErrorCodeEnum.PAD_ENGINEER_VERIFY_FAIL.getErrorCode());
                return messageVO;
            }

        } catch (Exception e) {
            throw new DataAccessException("【App_loginVerify】登陆验证失败", e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      获取平板广告(在线离线相结合)。
     * </desc>
     *
     * @param padDeviceUnique 平板deviceUnique
     * @param type 设备类型；1为梯控，2门禁 3云联动器
     * @param projectId 项目编号
     * @param deviceId  设备机号
     * @return
     * @author Qiang.S
     * @createDate 2018/05/14
     */
    @RequestMapping(path ="/getPadFaceADOffLine",method = RequestMethod.POST)
    @ResponseBody
    public MessageVO getPadFaceADOffLine(String padDeviceUnique, String type, String projectId, String deviceId,String createTime,String sign,String language) {
        MessageVO messageVO;
        try {
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("padDeviceUnique", padDeviceUnique);
            params.put("createTime", createTime);
            params.put("language", language);
            params.put("type", type);
            params.put("projectId", projectId);
            params.put("deviceId", deviceId);
            //验证签名
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            //判断必要信息是否为空
            else if (StringUtils.isBlank(type) || StringUtils.isBlank(projectId) || StringUtils.isEmpty(deviceId) || StringUtils.isEmpty(language) || StringUtils.isBlank(createTime)) {
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? BaseErrorCodeEnum.NOT_PARAM.getErrorCode() : BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                return new MessageVO(errorCode);
            }
            // 梯控
            List<AppPadADVO> padADVO = null;
            String isStart = null;
            //获取人脸识别使用key
            OperateFaceApplyInfoVO operateFaceApplyInfoVO = null;
            //云电梯
            if ("1".equals(type)) {
                padADVO = iAppPadFaceServiceClient.getElevatorAD(projectId, deviceId);
                isStart = iAppPadFaceServiceClient.elevatorAuthorityCheck(projectId, deviceId, "12", "1");
                operateFaceApplyInfoVO = iOperateFaceApplyServiceClient.getElevatorFaceByProjectId(projectId);
            }
            //门禁
            else if ("2".equals(type) || "3".equals(type)) {
                padADVO = iAppPadFaceServiceClient.getEntranceAD(projectId, deviceId);
                isStart = iAppPadFaceServiceClient.entranceAuthorityCheck(projectId, deviceId, "1");
                operateFaceApplyInfoVO = iOperateFaceApplyServiceClient.getFaceByProjectId(projectId);
            }
            StringBuffer sb = new StringBuffer();
            if (padADVO != null) {
                padADVO.forEach(padAD -> sb.append(padAD.getAttacheFileUrl() + ","));
            }
            AppPadADKeyVO appPadADKeyVO = new AppPadADKeyVO();
            appPadADKeyVO.setPadADVO(sb.toString());
            appPadADKeyVO.setIsStart(isStart == null ? "0" : isStart);
            if (operateFaceApplyInfoVO != null) {
                appPadADKeyVO.setAppId(operateFaceApplyInfoVO.getAppId());
                appPadADKeyVO.setApiKey(operateFaceApplyInfoVO.getApiKey());
                appPadADKeyVO.setSecretKey(operateFaceApplyInfoVO.getSecretKey());
                appPadADKeyVO.setFaceScore(operateFaceApplyInfoVO.getFaceScore());
                appPadADKeyVO.setFaceliveness(operateFaceApplyInfoVO.getFaceliveness());
            }
            OperateProjectDetailVO detailVO = iOperateProjectServiceClient.getDetail(projectId);
            if (detailVO != null) {
                appPadADKeyVO.setOnOffLinePadFace(detailVO.getOnOffLinePadFace());
                appPadADKeyVO.setDataTime(detailVO.getDataTime()==null?60:detailVO.getDataTime());
            }
            //物业增值功能：1开启，0关闭
            ProjectPO oneProject = iOperateProjectServiceClient.getOneProject(projectId);
            if (oneProject == null) {
                LOG.info("try空指针问题追踪projectId" + projectId + "，padDeviceUnique" + padDeviceUnique);
            }
            appPadADKeyVO.setPropertyValueOpen(oneProject.getPropertyValueOpen());
            //获取该项目设备云服务费时间是否过期
//            String endTime = iAppPadFaceServiceClient.getDeviceCloudServiceCostEndTime(projectId);
//            if(StringUtils.isEmpty(endTime)){
//                endTime="";
//            }
            appPadADKeyVO.setDeviceEndTime("");
            redisService.set(RedisConstant.DEVICE_PAD_IS_ONLINE_KEY+projectId+"4"+padDeviceUnique,RedisConstant.DEVICE_PAD_IS_ONLINE_CACHE_TIME,"1");//保存平板在线信息
            //取得iot信息
            CloudElevatorVO vo = iAppPadFaceServiceClient.registerPadIot(projectId+"4"+padDeviceUnique);
            if (vo != null) {
                appPadADKeyVO.setIotDeviceSecret(vo.getIotDeviceSecret());
                appPadADKeyVO.setIotProductKey(vo.getIotProductKey());
            }
            //广告缓存使用1,iot在线缓存使用2,当平板iot在线时轮询在线无视
            if (redisService.get(RedisConstant.DEVICE_PAD_IS_ONLINE_KEY+projectId+"4"+padDeviceUnique) == null ||
                    (redisService.get(RedisConstant.DEVICE_PAD_IS_ONLINE_KEY+projectId+"4"+deviceId) != null && !redisService.get(RedisConstant.DEVICE_PAD_IS_ONLINE_KEY+projectId+"4"+deviceId).equals("2"))) {
                redisService.set(RedisConstant.DEVICE_PAD_IS_ONLINE_KEY+projectId+"4"+padDeviceUnique,RedisConstant.DEVICE_PAD_IS_ONLINE_CACHE_TIME,"1");//保存平板在线信息
            }
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),appPadADKeyVO);
        } catch (Exception e) {
            LOG.info("catch空指针问题追踪projectId" + projectId + "，padDeviceUnique" + padDeviceUnique);
            throw new DataAccessException("【App_getAD】获取平板广告失败", e);
        }
        return messageVO;
    }

    /**
     * <desc>
     * 上传通行记录。
     * </desc>
     *
     * @param appUploadPassRecordDTO 设备类型；1为梯控，2门禁
     * @return
     * @author Qiang.S
     * @createDate 2018/05/16
     */
    @RequestMapping(path = "/uploadPassRecord", method = RequestMethod.POST)
    @ResponseBody
    public MessageVO uploadPassRecord(AppUploadPassRecordDTO appUploadPassRecordDTO, String sign) {
        MessageVO messageVO = new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), false);
        try {
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("createTime", appUploadPassRecordDTO.getCreateTime());
            params.put("language", appUploadPassRecordDTO.getLanguage());
            params.put("projectId", appUploadPassRecordDTO.getProjectId());
            params.put("passTime", appUploadPassRecordDTO.getPassTime());
            params.put("uId", appUploadPassRecordDTO.getUId());
            params.put("type", appUploadPassRecordDTO.getType());
            params.put("deviceId", appUploadPassRecordDTO.getDeviceId());
            params.put("imageStr", appUploadPassRecordDTO.getImageStr());
            params.put("imageType", appUploadPassRecordDTO.getImageType());
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(appUploadPassRecordDTO.getLanguage()) ? AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode() : AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                return new MessageVO(errorCode);
            }
            //判断必要信息是否为空
            else if (StringUtils.isBlank(appUploadPassRecordDTO.getImageStr()) || StringUtils.isBlank(appUploadPassRecordDTO.getCreateTime())
                    || StringUtils.isEmpty(appUploadPassRecordDTO.getImageType()) || StringUtils.isEmpty(appUploadPassRecordDTO.getLanguage())
                    || StringUtils.isEmpty(appUploadPassRecordDTO.getPassTime()) || StringUtils.isEmpty(appUploadPassRecordDTO.getType())
                    || StringUtils.isEmpty(appUploadPassRecordDTO.getUId()) || StringUtils.isEmpty(appUploadPassRecordDTO.getDeviceId())) {
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(appUploadPassRecordDTO.getLanguage()) ? BaseErrorCodeEnum.NOT_PARAM.getErrorCode() : BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                return new MessageVO(errorCode);
            }
            if(appUploadPassRecordDTO.getType().equals("3")){
                appUploadPassRecordDTO.setType("2");
            }
            appUploadPassRecordDTO.setUploadTime(appUploadPassRecordDTO.getCreateTime());
            AppPadDeviceVO appPadDeviceVO = iAppPadFaceServiceClient.getDeviceUnique(appUploadPassRecordDTO.getType(), appUploadPassRecordDTO.getProjectId(),
                    appUploadPassRecordDTO.getDeviceId());
            appUploadPassRecordDTO.setDeviceUnique(appPadDeviceVO.getDeviceUnique());
            appUploadPassRecordDTO.setDeviceName(appPadDeviceVO.getDeviceName());
            String uploadFilePath = uploadImageFile(appUploadPassRecordDTO.getImageStr(), appUploadPassRecordDTO.getImageType(), FileCatalogEnum.FACE_PASS_FILE);
            if (!StringUtils.isBlank(uploadFilePath)) {
                appUploadPassRecordDTO.setUploadFilePath(uploadFilePath);
                iCloudIntercomServiceClient.pushPadFaceRecord(appUploadPassRecordDTO);
                messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), true);
            }
        } catch (Exception e) {
            throw new DataAccessException("【App_uploadPassRecord】上传通行记录失败", e);
        }
        return messageVO;
    }

    /**
     * <desc>
     * 获取平板更新信息。
     * </desc>
     *
     * @param type 更新类型；1为人脸识别客户端，2为人脸识别服务端
     * @return
     * @author Qiang.S
     * @createDate 2018/05/31
     */
    @RequestMapping(path = "/getPadProgramInfo", method = RequestMethod.POST)
    @ResponseBody
    public MessageVO getPadProgramInfo(String createTime,String sign,String language,String type) {
        MessageVO messageVO;
        try {
            Map<String, String> params = new HashMap<>();
            params.put("createTime", createTime);
            params.put("language", language);
            //验证签名
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            if(StringUtils.isEmpty(type)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            // 查询平板更新信息
            AppPadProgramInfoVO appPadProgramInfoVO = iAppPadFaceServiceClient.getPadProgramInfo(type);
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),appPadProgramInfoVO);
        } catch (Exception e) {
            throw new DataAccessException("【App_getPadProgramInfo】获取平板更新信息失败", e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      平板增量获取变更数据接口
     * </desc>
     *
     * @param deviceId 与平板绑定的deviceUnique
     * @param padDeviceUnique 平板deviceUnique
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/01/18
     */
    @RequestMapping(path = "/getIncrementUpdate", method = RequestMethod.POST)
    @ResponseBody
    public MessageVO getIncrementUpdate(String deviceId, String padDeviceUnique, String token, String createTime, String sign, String language) {
        try {
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("createTime", createTime);
            params.put("language", language);
            params.put("deviceId", deviceId);
            params.put("padDeviceUnique", padDeviceUnique);
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode() : AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                return new MessageVO(errorCode);
            }
            if (StringUtils.isBlank(padDeviceUnique)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            List<PadIncrementUpdateGetVO> padIncrementUpdateGetVOS = iPadFaceSyncDataServiceClient.getIncrementUpdate(padDeviceUnique);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),padIncrementUpdateGetVOS);
        } catch (Exception e) {
            throw new DataAccessException("【App_getIncrementUpdate】平板增量获取变更数据失败", e);
        }
    }

    /**
     * <desc>
     *      修改同步状态为同步结束
     * </desc>
     *
     * @param syncSerialNo 同步流水号，多个用英文逗号相连
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/01/18
     */
    @RequestMapping(path = "/updateSyncStatus", method = RequestMethod.POST)
    @ResponseBody
    public MessageVO updateSyncStatus(String syncSerialNo, String token, String createTime, String sign, String language){
        try {
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("createTime", createTime);
            params.put("language", language);
            params.put("syncSerialNo", syncSerialNo);
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode() : AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                return new MessageVO(errorCode);
            }
            if (StringUtils.isBlank(syncSerialNo)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            iPadFaceSyncDataServiceClient.updateSyncStatus(syncSerialNo);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【App_updateSyncStatus】修改平板同步数据同步状态失败", e);
        }
    }

    /**
     * <desc>
     *      上传图片文件
     * </desc>
     *
     * @param imageStr  图片二进制
     * @param imageType 图片类型
     * @return
     * @author Qiang.S
     * @createDate 2018-05-07
     */
    private String uploadImageFile(String imageStr, String imageType, FileCatalogEnum fileCatalog) {
        try {
            imageStr = URLDecoder.decode(imageStr, "UTF-8");
        } catch (Exception e) {
            LOG.info("imageStr URLDecoder失败", e);
            return null;
        }
        byte[] bytes = null;
        try {
            bytes = new BASE64Decoder().decodeBuffer(imageStr);
        } catch (IOException e) {
            LOG.info("BASE64Decoder().decodeBuffer失败,imageStr不合法", e);
            return null;
        }
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                byteArrayInputStream,
                imageType,
                FILE_ACCESS_URL,
                fileCatalog.getType()
        );
        try {
            Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
            String returnCode = resultMap.get("returnCode").toString();
            if ("true".equals(returnCode)) {
                String fileUrl = resultMap.get("accessPath").toString();
                return fileUrl;
            } else {
                LOG.info(String.format("图片上传失败，returnCode: %s", returnCode));
                return null;
            }
        } catch (IOException e) {
            LOG.info("UploadFileUtil.uploadFile失败", e);
            return null;
        }
    }

    /**
     * <desc>
     *      平板获取全量数据
     * </desc>
     *
     * @param createTime
     * @param sign
     * @param language
     * @param deviceId  绑定设备序列号
     * @param padDeviceUnique   平板设备序列号
     * @param bandType 绑定设备类型  1电梯 2门禁
     * @return
     * @author Jiaqi.X
     * @createDate 2019/01/23
     */
    @RequestMapping(path = "/pullFull", method = RequestMethod.POST)
    @ResponseBody
    public MessageVO pullFull(String createTime, String sign, String language,String deviceId,String padDeviceUnique,Integer bandType){
        try {
            if(bandType==3){
                bandType=2;
            }
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("createTime", createTime);
            params.put("language", language);
            params.put("deviceId", deviceId);
            params.put("padDeviceUnique", padDeviceUnique);
            params.put("bandType", bandType.toString());
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode() : AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                return new MessageVO(errorCode);
            }
            String projectId = StringHandlerUtil.getProjectIdByDeviceUnique(padDeviceUnique);
            Map<String,Object> result = iPadFaceSyncDataServiceClient.pullFull(deviceId,padDeviceUnique,bandType);
            List<Map<String,Object>> users = (List<Map<String,Object>>)result.get("userInfos");
            List<Map<String,Object>> auths = new ArrayList<>();
            if (users != null) {
                for(Map<String,Object> user : users) {
                    if(user.get("houseUserType").toString().equals("5")) {
                        Map<String, Object> auth = new HashMap<String, Object>();
                        if (bandType == 2) {
                            //门禁
                            List<AppDoorDevicesVO> doors = iAppDeviceServiceClient.getDoorDevices(user.get("userId").toString(), StringHandlerUtil.getProjectIdByDeviceUnique(padDeviceUnique), 0);
                            List<Map<String, Object>> sysAuths = new ArrayList<>();
                            auth.put("userId", user.get("userId").toString());
                            auth.put("houseUserType",user.get("houseUserType").toString());
                            auth.put("deviceType", 1);
                            for (AppDoorDevicesVO door : doors) {
                                Map<String, Object> sysAuth = new HashMap<>();
                                sysAuth.put("auth", "8");
                                sysAuth.put("deviceUnique", door.getDeviceUnique());
                                sysAuths.add(sysAuth);
                            }
                            auth.put("sysAuths", sysAuths);
                        } else if (bandType == 1) {
                            //电梯
                            List<AppFloorDevicesVO> floors = iAppDeviceServiceClient.getFloorDevices(user.get("userId").toString(), StringHandlerUtil.getProjectIdByDeviceUnique(padDeviceUnique), 0);
                            List<Map<String, Object>> sysAuths = new ArrayList<>();
                            auth.put("userId", user.get("userId").toString());
                            auth.put("houseUserType",user.get("houseUserType").toString());
                            auth.put("deviceType", 2);
                            for (AppFloorDevicesVO floor : floors) {
                                Map<String, Object> sysAuth = new HashMap<>();
                                sysAuth.put("auth", floor.getLiveFloor());
                                sysAuth.put("deviceUnique", floor.getDeviceUnique());
                                sysAuths.add(sysAuth);
                            }
                            auth.put("sysAuths", sysAuths);
                        }
                        auths.add(auth);
                    }else{
                        //访客
                        Map<String, Object> auth = new HashMap<String, Object>();
                        if (bandType == 2) {
                            String entrances[] = user.get("deviceId") != null ? StringHandlerUtil.splitString(user.get("deviceId").toString()) : null;
                            if(entrances != null) {
                                //门禁
                                List<Map<String, Object>> sysAuths = new ArrayList<>();
                                auth.put("userId", user.get("userId").toString());
                                auth.put("houseUserType",user.get("houseUserType").toString());
                                auth.put("deviceType", 1);
                                auth.put("startTime",user.get("startTime"));
                                auth.put("endTime",user.get("endTime"));
                                for (String entrance : entrances) {
                                    Map<String, Object> sysAuth = new HashMap<>();
                                    sysAuth.put("auth", "8");
                                    sysAuth.put("deviceUnique", projectId+"2"+entrance);
                                    sysAuths.add(sysAuth);
                                }
                                auth.put("sysAuths", sysAuths);
                            }
                        } else if (bandType == 1) {
                            //电梯
                            List<Map<String,Object>> elevators = iPadFaceSyncDataServiceClient.getElevatorsByUnitId(user.get("unitId").toString(), user.get("floorNum").toString());
                            List<Map<String, Object>> sysAuths = new ArrayList<>();
                            auth.put("userId", user.get("userId").toString());
                            auth.put("houseUserType",user.get("houseUserType").toString());
                            auth.put("deviceType", 2);
                            auth.put("startTime",user.get("startTime"));
                            auth.put("endTime",user.get("endTime"));
                            for (Map<String,Object> floor : elevators) {
                                Map<String, Object> sysAuth = new HashMap<>();
                                sysAuth.put("auth", floor.get("auth").toString());
                                sysAuth.put("deviceUnique", floor.get("deviceUnique").toString());
                                sysAuths.add(sysAuth);
                            }
                            auth.put("sysAuths", sysAuths);
                        }
                        auths.add(auth);
                    }
                    user.remove("floorNum");
                    user.remove("deviceId");
                    user.remove("unitId");
                }
            }
            result.put("devices",auths);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),result);
        } catch (Exception e) {
            throw new DataAccessException("【App_pullFull】平板获取全量数据失败", e);
        }
    }

    /**
     * <desc>
     *      平板设备验证（在线）。
     * </desc>
     *
     * @param type 设备类型；1为梯控，2门禁
     * @param projectId 项目ID
     * @param deviceId 设备机号
     * @return
     * @author Qiang.S
     * @createDate 2018/05/14
     */
    @RequestMapping(path ="/deviceVerify",method = RequestMethod.POST)
    @ResponseBody
    public MessageVO deviceVerify(String type, String projectId,String deviceId, String createTime,String sign,String language) {
        MessageVO messageVO;
        try {
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("type",type);
            params.put("projectId",projectId);
            params.put("deviceId",deviceId);
            //验证签名
            if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            //判断必要信息是否为空
            else if (StringUtils.isBlank(type)||StringUtils.isBlank(createTime)|| StringUtils.isEmpty(projectId) || StringUtils.isEmpty(language) || StringUtils.isEmpty(deviceId)){
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode(): BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                return new MessageVO(errorCode);
            }
            //判断项目是否存在
            if (iOperateProjectServiceClient.checkProjectExist(projectId) <= 0){
                return new MessageVO(AppErrorCodeEnum.PAD_PROJECT_NOT_EXISTS.getErrorCode());
            }
            //判断当前项目是否被禁用
            if (iAppPadFaceServiceClient.checkProjectForbidden(projectId) > 0) {
                return new MessageVO(AppErrorCodeEnum.PAD_PROJECT_FORBIDDEN.getErrorCode());
            }
            String status = null;//设备状态
            //判断项目下是否有此设备,是否被禁用
            // 梯控
            if ("1".equals(type)) {
                status = iAppPadFaceServiceClient.elevatorAuthorityCheck(projectId,deviceId,"","");
            }
            //门禁
            else if ("2".equals(type) || "3".equals(type)) {
                status = iAppPadFaceServiceClient.entranceAuthorityCheck(projectId,deviceId,"");
            }
            //返回空则无此设备
            if (status == null || "".equals(status)) {
                return new MessageVO(AppErrorCodeEnum.PAD_DEVICE_NOT_EXISTS.getErrorCode());
            }
            //设备禁用
            if ("2".equals(status)) {
                return new MessageVO(AppErrorCodeEnum.PAD_DEVICE_FORBIDDEN.getErrorCode());
            }

            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),true);
        } catch (Exception e) {
            throw new DataAccessException("【App_deviceVerify】设备验证失败", e);
        }
        return  messageVO;
    }

    /**
     * <desc>
     *      获取平板广告(在线)。
     * </desc>
     *
     * @param type 设备类型；1为梯控，2门禁
     * @param projectId 项目编号
     * @param deviceId 设备机号
     * @return
     * @author Qiang.S
     * @createDate 2018/05/14
     */
    @RequestMapping(path ="/getPadFaceAD",method = RequestMethod.POST)
    @ResponseBody
    public MessageVO getPadFaceAD(String type, String projectId, String deviceId,String createTime,String sign,String language) {
        MessageVO messageVO;
        try {
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("createTime", createTime);
            params.put("language", language);
            params.put("type", type);
            params.put("projectId", projectId);
            params.put("deviceId", deviceId);
            //验证签名
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            //判断必要信息是否为空
            else if (StringUtils.isBlank(type) || StringUtils.isBlank(projectId) || StringUtils.isEmpty(deviceId) || StringUtils.isEmpty(language) || StringUtils.isBlank(createTime) ) {
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? BaseErrorCodeEnum.NOT_PARAM.getErrorCode() : BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                return new MessageVO(errorCode);
            }
            // 梯控
            List<AppPadADVO> padADVO = null;
            String isStart = null;
            //获取人脸识别使用key
            OperateFaceApplyInfoVO operateFaceApplyInfoVO = null;
            //云电梯
            if ("1".equals(type)) {
                padADVO= iAppPadFaceServiceClient.getElevatorAD(projectId,deviceId);
                isStart = iAppPadFaceServiceClient.elevatorAuthorityCheck(projectId,deviceId,"12","1");
                operateFaceApplyInfoVO = iOperateFaceApplyServiceClient.getElevatorFaceByProjectId(projectId);
            }
            //门禁
            else if ("2".equals(type) || "3".equals(type)) {
                padADVO = iAppPadFaceServiceClient.getEntranceAD(projectId,deviceId);
                isStart = iAppPadFaceServiceClient.entranceAuthorityCheck(projectId,deviceId,"1");
                operateFaceApplyInfoVO = iOperateFaceApplyServiceClient.getFaceByProjectId(projectId);
            }
            StringBuffer sb = new StringBuffer();
            if (padADVO != null) {
                padADVO.forEach(padAD -> sb.append(padAD.getAttacheFileUrl()+","));
            }
            AppPadADKeyVO appPadADKeyVO = new AppPadADKeyVO();
            appPadADKeyVO.setPadADVO(sb.toString());
            appPadADKeyVO.setIsStart(isStart==null?"0":isStart);
            if(operateFaceApplyInfoVO != null){
                appPadADKeyVO.setAppId(operateFaceApplyInfoVO.getAppId());
                appPadADKeyVO.setApiKey(operateFaceApplyInfoVO.getApiKey());
                appPadADKeyVO.setSecretKey(operateFaceApplyInfoVO.getSecretKey());
                appPadADKeyVO.setFaceScore(operateFaceApplyInfoVO.getFaceScore());
                appPadADKeyVO.setFaceliveness(operateFaceApplyInfoVO.getFaceliveness());
            }
            //物业增值功能：1开启，0关闭
            ProjectPO oneProject = iOperateProjectServiceClient.getOneProject(projectId);
            //获取该项目设备云服务费时间是否过期
//            String endTime = iAppPadFaceServiceClient.getDeviceCloudServiceCostEndTime(projectId);
//            if(StringUtils.isEmpty(endTime)){
//                endTime="";
//            }
//            appPadADKeyVO.setDeviceEndTime(endTime);
            appPadADKeyVO.setPropertyValueOpen(oneProject.getPropertyValueOpen());
            //广告缓存使用1,iot在线缓存使用2,当平板iot在线时轮询在线无视
            if (redisService.get(RedisConstant.DEVICE_PAD_IS_ONLINE_KEY+projectId+"4"+deviceId) == null ||
                    (redisService.get(RedisConstant.DEVICE_PAD_IS_ONLINE_KEY+projectId+"4"+deviceId) != null && !redisService.get(RedisConstant.DEVICE_PAD_IS_ONLINE_KEY+projectId+"4"+deviceId).equals("2"))) {
                redisService.set(RedisConstant.DEVICE_PAD_IS_ONLINE_KEY+projectId+"4"+deviceId,RedisConstant.DEVICE_PAD_IS_ONLINE_CACHE_TIME,"1");//保存平板在线信息
            }
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),appPadADKeyVO);
        } catch (Exception e) {
            throw new DataAccessException("【App_getAD】获取平板广告失败", e);
        }
        return  messageVO;
    }

    /**
     * <desc>
     *      离线平板绑定百度激活码。
     * </desc>
     *
     * @param projectId 项目ID
     * @param deviceId 设备唯一码deviceUnquie
     * @return
     * @author Juguang.S
     * @createDate 2019/03/13
     */
    @RequestMapping(path ="/deviceBinDingOffLine",method = RequestMethod.POST)
    @ResponseBody
    public MessageVO deviceBinDingOffLine(String projectId,String deviceId, String createTime,String sign,String language,String padDeviceUnique,String emId,String baiduId) {
        MessageVO messageVO;
        try {
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("projectId",projectId);
            params.put("deviceId",deviceId);
            params.put("padDeviceUnique",padDeviceUnique);
            params.put("emId",emId);
            params.put("baiduId",baiduId);
            //验证签名
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            //判断必要信息是否为空
            else if (StringUtils.isBlank(createTime)|| StringUtils.isEmpty(projectId) || StringUtils.isEmpty(language) || StringUtils.isEmpty(deviceId) || StringUtils.isEmpty(padDeviceUnique) || StringUtils.isEmpty(emId) || StringUtils.isEmpty(baiduId)){
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode(): BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                return new MessageVO(errorCode);
            }
            String type = deviceId.substring(8,9);
            if(type.equals("3")){
                type ="2";
            }
            deviceId = deviceId.substring(9,13);
            //判断项目是否存在
            if (iOperateProjectServiceClient.checkProjectExist(projectId) <= 0) {
                return new MessageVO(AppErrorCodeEnum.PAD_PROJECT_NOT_EXISTS.getErrorCode());
            }
            //判断当前项目是否被禁用
            if (iAppPadFaceServiceClient.checkProjectForbidden(projectId) > 0) {
                return new MessageVO(AppErrorCodeEnum.PAD_PROJECT_FORBIDDEN.getErrorCode());
            }
            //判断当前平板设备唯一码的设备是否存在或是否被禁用
            String padStatus = iAppPadFaceServiceClient.getPadDeviceExist(padDeviceUnique);
            if(padStatus == null || "".equals(padStatus)){
                return new MessageVO(AppErrorCodeEnum.PAD_DEVICE_NOT_EXISTS_STATUS.getErrorCode());
            }
            //设备禁用
            if ("2".equals(padStatus)) {
                return new MessageVO(AppErrorCodeEnum.PAD_DEVICE_FORBIDDEN.getErrorCode());
            }
            String status = null;//设备状态
            //判断项目下是否有此设备,是否被禁用
            // 梯控
            if ("1".equals(type)) {
                status = iAppPadFaceServiceClient.elevatorAuthorityCheck(projectId, deviceId, "", "");
            }
            //门禁
            else if ("2".equals(type)) {
                status = iAppPadFaceServiceClient.entranceAuthorityCheck(projectId, deviceId, "");
            }
            //返回空则无此设备
            if (status == null || "".equals(status)) {
                return new MessageVO(AppErrorCodeEnum.PAD_DEVICE_NOT_EXISTS.getErrorCode());
            }
            //设备禁用
            if ("2".equals(status)) {
                return new MessageVO(AppErrorCodeEnum.PAD_DEVICE_FORBIDDEN.getErrorCode());
            }
            //如果该baiduId是初次绑定则需校验该设备是否已购买
            Integer bingStatus = iCloudIntercomServiceClient.getBaiduIdBingStatus(baiduId);
            //根据deviceUnique查询该设备是否已绑定或已购买
            Integer buyOrBingStatus = iCloudIntercomServiceClient.getDeviceBuyOrBingStatus(padDeviceUnique);
            if(bingStatus == 0 && buyOrBingStatus == 0){
                return new MessageVO(CloudDeviceErrorCodeEnum.CLOUD_BAIDUCODE_IS_NOT_BUY.getErrorCode());
            }
            //根据baiduId来更新绑定百度识别授权码的设备信息
            String baiduCode = iAppPadFaceServiceClient.bingBaiDuAuthCode(projectId,emId,baiduId,padDeviceUnique,"2");
            if(StringUtils.isEmpty(baiduCode)){
                return new MessageVO(AppErrorCodeEnum.PAD_DEVICE_BAIDU_AUTH_CODE_EMPTY.getErrorCode());
            }
            Map<String,String> result = new HashMap<>();
            result.put("baiduCode",baiduCode);
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),result);
        } catch (Exception e) {
            throw new DataAccessException("【App_deviceBinDingOffLine】离线平板绑定百度激活码失败", e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      离线平板通知百度激活码结果。
     * </desc>
     *
     * @param baiduId 百度ID
     * @param code 3激活成功4激活失败
     * @param msg 失败信息
     * @return
     * @author Qiang.S
     * @createDate 2019/08/06
     */
    @RequestMapping(path ="/reportBaiDuAuthCode",method = RequestMethod.POST)
    @ResponseBody
    public MessageVO reportBaiDuAuthCode(String code,String msg, String createTime,String sign,String language,String baiduId) {
        MessageVO messageVO;
        try {
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("createTime",createTime);
            params.put("language",language);
            params.put("code",code);
            params.put("msg",msg);
            params.put("baiduId",baiduId);
            //验证签名
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            //判断必要信息是否为空
            else if (StringUtils.isBlank(createTime)|| StringUtils.isEmpty(language) || StringUtils.isEmpty(code) || StringUtils.isEmpty(baiduId)){
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language)?BaseErrorCodeEnum.NOT_PARAM.getErrorCode(): BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                return new MessageVO(errorCode);
            }
            //根据baiduId来更新绑定百度识别授权码的设备信息
            iAppPadFaceServiceClient.reportBaiDuAuthCode(baiduId,code,msg);
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【pad_reportBaiDuAuthCode】离线平板通知百度激活码结果失败", e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      用户读取欠费消息
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2019/05/28
     */
    @RequestMapping(path = "/getArrearageInfo", method = RequestMethod.POST)
    @ResponseBody
    public MessageVO getArrearageInfo(String projectId, String roomId, String deviceUnique, String userId, String type, String deviceType, String deviceId, String createTime, String sign, String language) {
        try {
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("createTime", createTime);
            params.put("language", language);
            params.put("projectId", projectId);
            params.put("roomId", roomId);
            params.put("userId", userId);
            params.put("type", type);
            params.put("deviceType", deviceType);
            params.put("deviceId", deviceId);
            params.put("deviceUnique", deviceUnique);
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode() : AppErrorCodeEnumEN.APP_SIGN_ERR.getErrorCode();
                return new MessageVO(errorCode);
            }
            if (StringUtils.isBlank(projectId) /*|| StringUtils.isBlank(roomId) || StringUtils.isBlank(userId)*/ || StringUtils.isBlank(type) || StringUtils.isBlank(deviceType)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if(deviceType.equals("3")){
                deviceType="2";
            }
            if ("12".equals(deviceType)) {
                deviceType = "1";
            }
            if ("22".equals(deviceType)) {
                deviceType = "2";
            }
            String qrCodeUrl = H5_PAYMENT_HTML + "?projectId=" + projectId + "&userId=" + userId + "&roomId=" + roomId + "&deviceType=" + deviceType + "&deviceId=" + deviceId;
            // roomId有逗号，进行一次编码
//            qrCodeUrl = URLEncoder.encode(qrCodeUrl, "UTF-8");
            // 生成二维码
//            ByteArrayOutputStream os = new ByteArrayOutputStream();
//            BufferedImage bim = QrcodeUtils.getQR_CODEBufferedImage(qrCodeUrl, BarcodeFormat.QR_CODE, 300, 300, QrcodeUtils.getDecodeHintType());
//            ImageIO.write(bim, "jpg", os);
//            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(os.toByteArray());
//            String QRCode = this.uploadFile(byteArrayInputStream);
//            String QRCode = new BASE64Encoder().encode(ByteStreams.toByteArray(byteArrayInputStream));
//            if (QRCode == null) {
//                QRCode = "";
//            }
            Map<String,String> data = iAppDeviceServiceClient.getArrearageInfo(projectId, roomId, deviceUnique, userId, type, deviceType);
            if (data != null && !data.isEmpty()) {
                data.put("QRCode", qrCodeUrl);
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), data);
        } catch (Exception e) {
            throw new DataAccessException("【App_getArrearageInfo】用户读取欠费消息失败", e);
        }
    }

    /**
     * <desc>
     *      Ftp上传文件，返回Url.
     * </desc>
     *
     * @param inputStream 文件流
     * @return 文件上传成功后会返回Url,否则返回空
     * @author wangzhi
     * @createDate 2019/05/28
     */
    private String uploadFile(InputStream inputStream) throws IOException {
        String fileUrl = "";
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                inputStream,
                "jpg",
                FILE_ACCESS_URL,
                FileCatalogEnum.DEVICEQRCODE_FILE.getType()
        );
        Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
        Boolean returnCode = (Boolean)resultMap.get("returnCode");
        if (returnCode == false){
            return fileUrl;
        }
        fileUrl = resultMap.get("accessPath").toString();
        return fileUrl;
    }
}
